package elicecn.swing.watermarker;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.HeadlessException;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.security.NoSuchAlgorithmException;
import java.text.NumberFormat;

import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.filechooser.FileFilter;

import elicecn.util.encrypt.CRC32;
import elicecn.util.encrypt.Encrypt;
import elicecn.util.encrypt.MessageDigest;

/**
 * 用于计算文件的数字水印。利用CRC32/MD5/SHA1等哈希算法计算文件的哈希值，构成文件的数字水印。
 * 
 * @author 屹砾
 * @email eli.wuhan@gmail.com
 * @time 2009-3-1
 */
public class Watermark extends JFrame implements ActionListener {
	private static final long serialVersionUID = -7593400618031498690L;
	private static String ENTER = null;
	static {
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (UnsupportedLookAndFeelException e) {
			e.printStackTrace();
		}
		if (System.getenv("OS").indexOf("Windows") != -1) {
			ENTER = "\r\n";
		} else {
			ENTER = "\n";
		}
	}

	class Text {
		static final String title = "文件水印验证程序";
		static final String cmdOpen = "打开...";
		static final String cmdGenerate = "全部生成";
		static final String cmdCheck = "全部验证";
		static final String cmdSaveAs = "保存";
		static final String cmdClear = "清空";

		static final String commonGenerateCRC32 = "生成 CRC32";
		static final char commonGenerateCRC32Mnemonic = '3';
		static final String commonCheckCRC32 = "验证 CRC32";
		static final char commonCheckCRC32Mnemonic = '2';

		static final String commonGenerateMD5 = "生成 MD5  ";
		static final char commonGenerateMD5Mnemonic = 'D';
		static final String commonCheckMD5 = "验证 MD5  ";
		static final char commonCheckMD5Mnemonic = 'M';

		static final String commonGenerateSHA1 = "生成 SHA1 ";
		static final char commonGenerateSHA1Mnemonic = 'S';
		static final String commonCheckSHA1 = "验证 SHA1 ";
		static final char commonCheckSHA1Mnemonic = 'H';

		static final String menuFile = "文件(F)";
		static final char menuFileMnemonic = 'F';
		static final String menuFileOpen = "打开(O)...";
		static final char menuFileOpenMnemonic = 'O';
		static final String menuFileSaveAs = "保存(S)...";
		static final char menuFileSaveAsMnemonic = 'S';
		static final String menuFileExit = "退出(X)";
		static final char menuFileExitMnemonic = 'X';

		static final String menuWatermark = "水印(W)";
		static final char menuWatermarkMnemonic = 'W';
		static final String menuWatermarkGenerateCRC32 = "生成 CRC32";
		static final char menuWatermarkGenerateCRC32Mnemonic = '3';
		static final String menuWatermarkCheckCRC32 = "验证 CRC32";
		static final char menuWatermarkCheckCRC32Mnemonic = '2';
		static final String menuWatermarkGenerateMD5 = "生成 MD5";
		static final char menuWatermarkGenerateMD5Mnemonic = 'D';
		static final String menuWatermarkCheckMD5 = "验证 MD5";
		static final char menuWatermarkCheckMD5Mnemonic = 'M';
		static final String menuWatermarkGenerateSHA1 = "生成 SHA1";
		static final char menuWatermarkGenerateSHA1Mnemonic = 'S';
		static final String menuWatermarkCheckSHA1 = "验证 SHA1";
		static final char menuWatermarkCheckSHA1Mnemonic = 'H';
		static final String menuWatermarkGenerateAll = "全部生成(A)";
		static final char menuWatermarkGenerateAllMnemonic = 'A';
		static final String menuWatermarkCheckAll = "全部验证(T)";
		static final char menuWatermarkCheckAllMnemonic = 'T';
		static final String menuWatermarkClearAll = "清空(L)";
		static final char menuWatermarkClearAllMnemonic = 'L';

		static final String menuHelp = "帮助(H)";
		static final char menuHelpMnemonic = 'H';
		static final String menuHelpContent = "主题(C)";
		static final char menuHelpContentMnemonic = 'C';
		static final String menuHelpContentTitle = "主题";
		static final String menuHelpContentMessage = "(C)2008 文件水印验证程序\nEmail: eli.wuhan@gmail.com";
		static final String menuHelpAbout = "关于(A)";
		static final char menuHelpAboutMnemonic = 'A';
		static final String menuHelpAboutTitle = "关于";
		static final String menuHelpAboutMessage = "(C)2008 文件水印验证程序\nEmail: eli.wuhan@gmail.com";

		static final String loadFileErrorMessage = "文件读取错误，请重试！";
		static final String loadFileErrorTitle = "警告";
		static final String compareSuccess = " 成功";
		static final String compareFailure = " 失败";
		static final String compareTitle = "消息";

		static final String saveFileType = "文本文档(*.txt)";
		static final String saveFileTypeExt = ".txt";
		static final String saveFileOverwrite = "文件已存在，是否覆盖？";
		static final String saveFileTitle = "消息";
		static final String saveFileOK = "文件已保存。";
		static final String saveFileFailure = "文件保存失败！";
		static final String saveFileKbErr = "此环境不支持键盘、显示器或鼠标！";
		static final String saveFileNonContent = "没有可以保存的内容。";
	}

	private CRC32 crc = null;
	private Encrypt md5 = null;
	private Encrypt sha1 = null;
	private Container container = null;

	protected JTextField filePath = null;
	private JButton filePathOpen = null;
	protected JButton generateAll = null;
	private JButton compareAll = null;
	private JButton saveAs = null;
	private JButton clearAll = null;

	private JTextField resultCRC32 = null;
	private JButton resultButtonCRC32 = null;
	private JTextField compareCRC32 = null;
	private JButton compareButtonCRC32 = null;

	private JTextField resultMD5 = null;
	private JButton resultButtonMD5 = null;
	private JTextField compareMD5 = null;
	private JButton compareButtonMD5 = null;

	private JTextField resultSHA1 = null;
	private JButton resultButtonSHA1 = null;
	private JTextField compareSHA1 = null;
	private JButton compareButtonSHA1 = null;

	private JMenuItem fileOpen = null;
	private JMenuItem fileSaveAs = null;
	private JMenuItem fileExit = null;
	private JMenuItem watermarkGenerateCRC32 = null;
	private JMenuItem watermarkCheckCRC32 = null;
	private JMenuItem watermarkGenerateMD5 = null;
	private JMenuItem watermarkCheckMD5 = null;
	private JMenuItem watermarkGenerateSHA1 = null;
	private JMenuItem watermarkCheckSHA1 = null;
	private JMenuItem watermarkGenerateAll = null;
	private JMenuItem watermarkCompareAll = null;
	private JMenuItem watermarkClearAll = null;
	private JMenuItem helpContent = null;
	private JMenuItem helpAbout = null;

	public Watermark() throws NoSuchAlgorithmException {

		crc = new CRC32();
		md5 = MessageDigest.getMD5Algorithm();
		sha1 = MessageDigest.getSHA1Algorithm();

		container = getContentPane();
		filePath = new JTextField();
		filePath.setDragEnabled(true);
		filePathOpen = new JButton();
		generateAll = new JButton();
		compareAll = new JButton();
		saveAs = new JButton();
		clearAll = new JButton();

		resultCRC32 = new JTextField();
		resultButtonCRC32 = new JButton();
		compareCRC32 = new JTextField();
		compareButtonCRC32 = new JButton();

		resultMD5 = new JTextField();
		resultButtonMD5 = new JButton();
		compareMD5 = new JTextField();
		compareButtonMD5 = new JButton();

		resultSHA1 = new JTextField();
		resultButtonSHA1 = new JButton();
		compareSHA1 = new JTextField();
		compareButtonSHA1 = new JButton();

		buildPane();
		buildMenu();
		configureComponents();
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(new Dimension(360, 240));
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		setBounds((screenSize.width - getSize().width) / 2,
				(screenSize.height - getSize().height) / 3, getSize().width,
				getSize().height);
		// setResizable(false);
		pack();
	}

	private void configureComponents() {
		setTitle(Text.title);
		URL url = getClass().getResource("elice.png");
		if (url != null)
			setIconImage(new ImageIcon(url).getImage());
		filePathOpen.setText(Text.cmdOpen);
		filePathOpen.addActionListener(this);
		generateAll.setText(Text.cmdGenerate);
		generateAll.addActionListener(this);
		compareAll.setText(Text.cmdCheck);
		compareAll.addActionListener(this);
		saveAs.setText(Text.cmdSaveAs);
		saveAs.addActionListener(this);
		clearAll.setText(Text.cmdClear);
		clearAll.addActionListener(this);

		resultButtonCRC32.setText(Text.commonGenerateCRC32);
		resultButtonCRC32.setMnemonic(Text.commonGenerateCRC32Mnemonic);
		resultButtonCRC32.addActionListener(this);

		compareButtonCRC32.setText(Text.commonCheckCRC32);
		compareButtonCRC32.setMnemonic(Text.commonCheckCRC32Mnemonic);
		compareButtonCRC32.addActionListener(this);

		resultButtonMD5.setText(Text.commonGenerateMD5);
		resultButtonMD5.setMnemonic(Text.commonGenerateMD5Mnemonic);
		resultButtonMD5.addActionListener(this);

		compareButtonMD5.setText(Text.commonCheckMD5);
		compareButtonMD5.setMnemonic(Text.commonCheckMD5Mnemonic);
		compareButtonMD5.addActionListener(this);

		resultButtonSHA1.setText(Text.commonGenerateSHA1);
		resultButtonSHA1.setMnemonic(Text.commonGenerateSHA1Mnemonic);
		resultButtonSHA1.addActionListener(this);

		compareButtonSHA1.setText(Text.commonCheckSHA1);
		compareButtonSHA1.setMnemonic(Text.commonCheckSHA1Mnemonic);
		compareButtonSHA1.addActionListener(this);

		filePath.setEditable(false);
		filePath.setTransferHandler(new FilePathTransferHandler(this));
		resultCRC32.setEditable(false);
		compareCRC32.setEditable(true);
		resultMD5.setEditable(false);
		compareMD5.setEditable(true);
		resultSHA1.setEditable(false);
		compareSHA1.setEditable(true);

		resultCRC32.setHorizontalAlignment(JTextField.CENTER);
		compareCRC32.setHorizontalAlignment(JTextField.CENTER);
		resultMD5.setHorizontalAlignment(JTextField.CENTER);
		compareMD5.setHorizontalAlignment(JTextField.CENTER);
		resultSHA1.setHorizontalAlignment(JTextField.CENTER);
		compareSHA1.setHorizontalAlignment(JTextField.CENTER);
		resultCRC32.setSize(resultMD5.getPreferredSize());
		compareCRC32.setSize(compareMD5.getPreferredSize());
		resultMD5.setSize(resultMD5.getPreferredSize());
		compareMD5.setSize(compareMD5.getPreferredSize());
		resultSHA1.setSize(resultSHA1.getPreferredSize());
		compareSHA1.setSize(compareSHA1.getPreferredSize());
	}

	private void buildMenu() {
		setJMenuBar(new JMenuBar());

		// 文件菜单项
		JMenu file = getJMenuBar().add(new JMenu(Text.menuFile));
		file.setMnemonic(Text.menuFileMnemonic);

		fileOpen = file.add(new JMenuItem(Text.menuFileOpen));
		fileOpen.setMnemonic(Text.menuFileOpenMnemonic);
		fileOpen.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O,
				KeyEvent.CTRL_MASK));
		fileOpen.addActionListener(this);

		file.addSeparator();

		fileSaveAs = file.add(new JMenuItem(Text.menuFileSaveAs));
		fileSaveAs.setMnemonic(Text.menuFileSaveAsMnemonic);
		fileSaveAs.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
				KeyEvent.CTRL_MASK));
		fileSaveAs.addActionListener(this);

		file.addSeparator();

		fileExit = file.add(new JMenuItem(Text.menuFileExit));
		fileExit.setMnemonic(Text.menuFileExitMnemonic);
		fileExit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4,
				KeyEvent.ALT_MASK));
		fileExit.addActionListener(this);

		// 水印菜单项
		JMenu watermark = getJMenuBar().add(new JMenu(Text.menuWatermark));
		watermark.setMnemonic(Text.menuWatermarkMnemonic);

		watermarkGenerateCRC32 = watermark.add(new JMenuItem(
				Text.menuWatermarkGenerateCRC32));
		watermarkGenerateCRC32
				.setMnemonic(Text.menuWatermarkGenerateCRC32Mnemonic);
		watermarkGenerateCRC32.setAccelerator(KeyStroke.getKeyStroke(
				KeyEvent.VK_1, KeyEvent.CTRL_MASK));
		watermarkGenerateCRC32.addActionListener(this);

		watermarkCheckCRC32 = watermark.add(new JMenuItem(
				Text.menuWatermarkCheckCRC32));
		watermarkCheckCRC32.setMnemonic(Text.menuWatermarkCheckCRC32Mnemonic);
		watermarkCheckCRC32.setAccelerator(KeyStroke.getKeyStroke(
				KeyEvent.VK_2, KeyEvent.CTRL_MASK));
		watermarkCheckCRC32.addActionListener(this);

		watermark.addSeparator();

		watermarkGenerateMD5 = watermark.add(new JMenuItem(
				Text.menuWatermarkGenerateMD5));
		watermarkGenerateMD5.setMnemonic(Text.menuWatermarkGenerateMD5Mnemonic);
		watermarkGenerateMD5.setAccelerator(KeyStroke.getKeyStroke(
				KeyEvent.VK_3, KeyEvent.CTRL_MASK));
		watermarkGenerateMD5.addActionListener(this);

		watermarkCheckMD5 = watermark.add(new JMenuItem(
				Text.menuWatermarkCheckMD5));
		watermarkCheckMD5.setMnemonic(Text.menuWatermarkCheckMD5Mnemonic);
		watermarkCheckMD5.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_4,
				KeyEvent.CTRL_MASK));
		watermarkCheckMD5.addActionListener(this);

		watermark.addSeparator();

		watermarkGenerateSHA1 = watermark.add(new JMenuItem(
				Text.menuWatermarkGenerateSHA1));
		watermarkGenerateSHA1
				.setMnemonic(Text.menuWatermarkGenerateSHA1Mnemonic);
		watermarkGenerateSHA1.setAccelerator(KeyStroke.getKeyStroke(
				KeyEvent.VK_5, KeyEvent.CTRL_MASK));
		watermarkGenerateSHA1.addActionListener(this);

		watermarkCheckSHA1 = watermark.add(new JMenuItem(
				Text.menuWatermarkCheckSHA1));
		watermarkCheckSHA1.setMnemonic(Text.menuWatermarkCheckSHA1Mnemonic);
		watermarkCheckSHA1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_6,
				KeyEvent.CTRL_MASK));
		watermarkCheckSHA1.addActionListener(this);

		watermark.addSeparator();

		watermarkGenerateAll = watermark.add(new JMenuItem(
				Text.menuWatermarkGenerateAll));
		watermarkGenerateAll.setMnemonic(Text.menuWatermarkGenerateAllMnemonic);
		watermarkGenerateAll.setAccelerator(KeyStroke.getKeyStroke(
				KeyEvent.VK_7, KeyEvent.CTRL_MASK));
		watermarkGenerateAll.addActionListener(this);

		watermarkCompareAll = watermark.add(new JMenuItem(
				Text.menuWatermarkCheckAll));
		watermarkCompareAll.setMnemonic(Text.menuWatermarkCheckAllMnemonic);
		watermarkCompareAll.setAccelerator(KeyStroke.getKeyStroke(
				KeyEvent.VK_8, KeyEvent.CTRL_MASK));
		watermarkCompareAll.addActionListener(this);

		watermark.addSeparator();

		watermarkClearAll = watermark.add(new JMenuItem(
				Text.menuWatermarkClearAll));
		watermarkClearAll.setMnemonic(Text.menuWatermarkClearAllMnemonic);
		watermarkClearAll.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L,
				KeyEvent.CTRL_MASK));
		watermarkClearAll.addActionListener(this);

		// 帮助菜单项
		JMenu help = getJMenuBar().add(new JMenu(Text.menuHelp));
		help.setMnemonic(Text.menuHelpMnemonic);

		helpContent = help.add(new JMenuItem(Text.menuHelpContent));
		helpContent.setMnemonic(Text.menuHelpContentMnemonic);
		helpContent.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0));
		helpContent.addActionListener(this);

		help.addSeparator();

		helpAbout = help.add(new JMenuItem(Text.menuHelpAbout));
		helpAbout.setMnemonic(Text.menuHelpAboutMnemonic);
		helpAbout.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1,
				KeyEvent.CTRL_MASK));
		helpAbout.addActionListener(this);
	}

	private void buildPane() {
		JPanel northPanel = new JPanel();
		northPanel.setLayout(new BorderLayout());
		northPanel.add(filePath, BorderLayout.NORTH);

		JPanel top = new JPanel();
		top.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
		top.add(filePathOpen);
		top.add(generateAll);
		top.add(compareAll);
		top.add(saveAs);
		top.add(clearAll);
		northPanel.add(top, BorderLayout.CENTER);

		JPanel mainPane = new JPanel(new GridLayout(6, 1, 2, 2));
		JTextField[] texts = { resultCRC32, compareCRC32, resultMD5,
				compareMD5, resultSHA1, compareSHA1 };
		JButton[] buttons = { resultButtonCRC32, compareButtonCRC32,
				resultButtonMD5, compareButtonMD5, resultButtonSHA1,
				compareButtonSHA1 };
		int count = 6;
		for (int i = count; i > 0; i--) {
			JPanel panel = new JPanel();
			panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
			panel.add(texts[count - i]);
			panel.add(buttons[count - i]);
			mainPane.add(panel);
		}

		container.add(northPanel, BorderLayout.NORTH);
		container.add(mainPane, BorderLayout.CENTER);
	}

	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == filePathOpen || e.getSource() == fileOpen) {
			loadFile();
		} else if (e.getSource() == resultButtonCRC32
				|| e.getSource() == watermarkGenerateCRC32) {
			try {
				resultCRC32.setText(generate(filePath.getText(), crc));
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		} else if (e.getSource() == compareButtonCRC32
				|| e.getSource() == watermarkCheckCRC32) {
			try {
				compare(watermarkCheckCRC32.getText(), resultCRC32.getText(),
						compareCRC32.getText(), 8);
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		} else if (e.getSource() == resultButtonMD5
				|| e.getSource() == watermarkGenerateMD5) {
			try {
				resultMD5.setText(generate(filePath.getText(), md5));
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		} else if (e.getSource() == compareButtonMD5
				|| e.getSource() == watermarkCheckMD5) {
			try {
				compare(watermarkCheckMD5.getText(), resultMD5.getText(),
						compareMD5.getText(), 32);
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		} else if (e.getSource() == resultButtonSHA1
				|| e.getSource() == watermarkGenerateSHA1) {
			try {
				resultSHA1.setText(generate(filePath.getText(), sha1));
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		} else if (e.getSource() == compareButtonSHA1
				|| e.getSource() == watermarkCheckSHA1) {
			try {
				compare(watermarkCheckSHA1.getText(), resultSHA1.getText(),
						compareSHA1.getText(), 40);
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		} else if (e.getSource() == generateAll
				|| e.getSource() == watermarkGenerateAll) {
			try {
				resultCRC32.setText(generate(filePath.getText(), crc));
				resultMD5.setText(generate(filePath.getText(), md5));
				resultSHA1.setText(generate(filePath.getText(), sha1));
			} catch (Exception e1) {
				e1.printStackTrace();
			}
		} else if (e.getSource() == compareAll
				|| e.getSource() == watermarkCompareAll) {
			compareButtonCRC32.doClick();
			compareButtonMD5.doClick();
			compareButtonSHA1.doClick();
		} else if (e.getSource() == clearAll
				|| e.getSource() == watermarkClearAll) {
			filePath.setText(null);
			resultCRC32.setText(null);
			resultMD5.setText(null);
			resultSHA1.setText(null);
			compareCRC32.setText(null);
			compareMD5.setText(null);
			compareSHA1.setText(null);
		} else if (e.getSource() == saveAs || e.getSource() == fileSaveAs) {
			saveAs();
		} else if (e.getSource() == fileExit) {
			System.exit(0);
		} else if (e.getSource() == helpContent) {
			JOptionPane.showMessageDialog(this, Text.menuHelpContentMessage,
					Text.menuHelpContentTitle, JOptionPane.INFORMATION_MESSAGE);
		} else if (e.getSource() == helpAbout) {
			JOptionPane.showMessageDialog(this, Text.menuHelpAboutMessage,
					Text.menuHelpAboutTitle, JOptionPane.INFORMATION_MESSAGE);
		}
	}

	private boolean loadFile() {
		JFileChooser chooser = new JFileChooser();
		boolean loaded = false;
		int returnVal = 0;
		returnVal = chooser.showOpenDialog(this);
		if (returnVal == JFileChooser.APPROVE_OPTION) {
			String fileChosen = chooser.getCurrentDirectory() + File.separator
					+ chooser.getSelectedFile().getName();
			System.out.println("[file] " + fileChosen);
			filePath.setText(fileChosen);
			resultCRC32.setText(null);
			resultMD5.setText(null);
			resultSHA1.setText(null);
			loaded = true;
		}
		return loaded;
	}

	private String generate(String filename, Encrypt enc) throws Exception {
		File file = new File(filename);
		String code = null;
		try {
			code = enc.calc(file);
		} catch (Exception e) {
			System.out.println(Text.loadFileErrorMessage);
			e.printStackTrace();
			JOptionPane.showMessageDialog(this, Text.loadFileErrorMessage,
					Text.loadFileErrorTitle, JOptionPane.ERROR_MESSAGE);
			throw e;
		}
		return code;
	}

	private void compare(String preMessage, String code, String compare,
			int length) throws Exception {
		boolean flag = false;
		String message = null;
		int messageType = JOptionPane.ERROR_MESSAGE;
		if (code.length() == length && compare.length() == length
				&& code.equalsIgnoreCase(compare)) {
			flag = true;
			message = preMessage + Text.compareSuccess;
			messageType = JOptionPane.INFORMATION_MESSAGE;
		} else {
			message = preMessage + Text.compareFailure;
		}
		JOptionPane.showMessageDialog(this, message, Text.compareTitle,
				messageType);
		if (!flag) {
			throw new Exception(message);
		}
	}

	private void saveAs() {
		String src = filePath.getText();
		if (src.length() > 0
				&& (resultCRC32.getText().length() > 0
						|| resultButtonMD5.getText().length() > 0 || resultButtonSHA1
						.getText().length() > 0)) {
			try {
				String defaultfile = src.substring(0, src.lastIndexOf("."))
						+ "-WATERMARK";
				String filename = getSaveAsFilename(defaultfile);
				File file = new File(filename);
				FileWriter writer = new FileWriter(file);

				File srcfile = new File(src);
				String[] name = { "CRC32 : ", "  MD5 : ", " SHA1 : " };
				String[] code = { resultCRC32.getText(), resultMD5.getText(),
						resultSHA1.getText() };
				String content = getSaveAsContent(srcfile, name, code);

				writer.write(content);
				writer.flush();
				writer.close();
				JOptionPane.showMessageDialog(this, Text.saveFileOK + "\n"
						+ file.getName(), Text.saveFileTitle,
						JOptionPane.INFORMATION_MESSAGE);
			} catch (HeadlessException e) {
				e.printStackTrace();
				JOptionPane.showMessageDialog(this, Text.saveFileKbErr,
						Text.saveFileTitle, JOptionPane.ERROR_MESSAGE);
			} catch (IOException e) {
				e.printStackTrace();
				JOptionPane.showMessageDialog(this, Text.saveFileFailure,
						Text.saveFileTitle, JOptionPane.ERROR_MESSAGE);
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else {
			JOptionPane.showMessageDialog(this, Text.saveFileNonContent,
					Text.saveFileTitle, JOptionPane.ERROR_MESSAGE);
		}
	}

	private String getSaveAsFilename(String defaultfile) throws Exception {
		// 选择文件名
		JFileChooser chooser = new JFileChooser();
		String fileChosen = null;
		chooser.setSelectedFile(new File(defaultfile));
		chooser.setAcceptAllFileFilterUsed(false);
		chooser.setFileFilter(new FileFilter() {
			public boolean accept(File f) {
				if (f.getName().toLowerCase().endsWith(Text.saveFileTypeExt)) {
					return true;
				} else {
					return false;
				}
			}

			public String getDescription() {
				return Text.saveFileType;
			}
		});
		while (true) {
			int returnVal = chooser.showSaveDialog(this);
			if (returnVal == JFileChooser.APPROVE_OPTION) {
				fileChosen = chooser.getCurrentDirectory() + File.separator
						+ chooser.getSelectedFile().getName();
				if (!fileChosen.toLowerCase().endsWith(Text.saveFileTypeExt)) {
					fileChosen += Text.saveFileTypeExt;
				}
				File file = new File(fileChosen);
				if (file.exists()) {
					if (JOptionPane.showConfirmDialog(this,
							Text.saveFileOverwrite, Text.saveFileTitle,
							JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
						break;
					}
				} else {
					break;
				}
				System.out.println("[file] " + fileChosen);
			} else {
				throw new Exception();
			}
		}
		return fileChosen;
	}

	private String getSaveAsContent(File srcfile, String[] name, String[] code) {
		StringBuffer buf = new StringBuffer();
		{// 文件名和文件大小
			NumberFormat format = NumberFormat.getNumberInstance();
			format.setMaximumFractionDigits(0);
			format.setMinimumFractionDigits(0);
			buf.append(" file : ");
			buf.append(srcfile.getName());
			buf.append(ENTER);
			buf.append(" size : ");
			buf.append(format.format(srcfile.length()));
			buf.append(" B");
			double size = srcfile.length();
			String[] unit = { " KB", " MB", " GB", " TB" };
			format.setMaximumFractionDigits(2);
			format.setMinimumFractionDigits(2);
			for (int i = 0; i < 4; i++) {
				size /= 1 << 10;
				if (Math.floor(size) > 0) {
					buf.append(" => ");
					buf.append(format.format(size));
					buf.append(unit[i]);
				}
			}
			buf.append(ENTER);
		}
		for (int i = 0; i < name.length; i++) {
			if (code[i] != null) {
				buf.append(name[i]);
				buf.append(code[i]);
				buf.append(ENTER);
			}
		}
		return buf.toString();
	}

	public static void main(String[] args) throws NoSuchAlgorithmException {
		Watermark pane = new Watermark();
		pane.setResizable(false);
		pane.setVisible(true);
	}
}
